package org.gw.building.ctrl;

import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.ILock;
import com.hazelcast.core.IMap;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ArrayUtils;
import org.gw.building.model.*;
import org.gw.building.repositories.*;
import org.gw.building.util.FileHelper;
import org.gw.building.util.TrainUtil;
import org.gw.ylc.base.context.RequestContextHolder;
import org.gw.ylc.base.interceptor.RequestPermission;
import org.gw.ylc.base.model.UserInfo;
import org.gw.ylc.base.util.PermissionUtil;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 课程
 * 
 * @author babyv
 *
 */
@Controller
@RequestMapping("course")
public class CourseCtrl implements InitializingBean {
	@Autowired
	private TermRepository termRepositories;
	@Autowired
	private CourseInfoRepository courseRepositories;
	@Autowired
	private CourseApplyRepository courseApplyRepository;
	@Autowired
	private StuInfoRepository stuInfoRepository;
	@Autowired
	private MessageRepository messageRepository;
	@Autowired
	private MessageReadStateRepository messageReadStateRepository;
	@Autowired
	private CourseAttendanceRepository courseAttendanceRepository;
	@Autowired
	private TermCtrl termCtrl;
	@Autowired
	private HazelcastInstance hazelcastInstance;
	private IMap<String, Long> applyCountMap;
	private IMap<String, CourseInfo> courseInfoMap;
	public static final String APPLYCOUNTLOCK = "train.CourseApply.Lock";
	public static final String APPLYCOUNTKEY = "train.CourseApply.Count";
	public static final String COURSEINFOKEY = "train.CourseInfo";
	private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

	/**
	 * 添加课程
	 * 
	 * @param course
	 * @return
	 */
	@RequestMapping("addCourse")
	@ResponseBody
	@RequestPermission(value = RequestPermission.SCHOOL)
	@Transactional
	public Object addCourse(CourseInfo course) {
		CourseInfo saved;
		// 当前启用期次
		Message message = new Message();
		if (StringUtils.hasText(course.getId())) {
			saved = courseRepositories.save(course);
			message = messageRepository.findFirstByBizTypeAndBizId(Message.COURSE_PUBLISH_TYPE, saved.getId());
		} else {
			// course.setTerm(termRepositories.getCurrentTerm());
			saved = courseRepositories.save(course);
		}
		message.setBizType(Message.COURSE_PUBLISH_TYPE);
		message.setBizId(saved.getId());
		message.setFbdx("all");
		message.setFsfs("0");
		String kclb = course.getKclb();
		String type = "";
		if ("1".equals(kclb)) {
			type = "【必修】";
		} else if ("2".equals(kclb)) {
			type = "【选修】";
		} else if ("3".equals(kclb)) {
			type = "【体验】";
		}
		message.setFsnr("最新" + type + "课程 " + course.getName() + " ,将于 "
				+ new SimpleDateFormat("yyyy-MM-dd HH:mm").format(course.getFbsj()) + " 开放报名邀请你来参加！");
		message.setFsr("系统管理员");
		message.setFssj(new Date());
		courseInfoMap.remove(saved.getId());
		messageRepository.save(message);
		return saved;
	}

	@RequestMapping("deleteCourse")
	@ResponseBody
	@RequestPermission(value = RequestPermission.SCHOOL)
	public Object deleteCourse(String id) {
		messageRepository.deleteByBizTypeAndBizId(Message.COURSE_PUBLISH_TYPE, id);
		courseRepositories.delete(id);
		return id;
	}

	@RequestMapping("queryCourse")
	@ResponseBody
	@RequestPermission(value = { RequestPermission.SCHOOL, RequestPermission.DEPARTMENT })
	public Page<CourseInfo> queryCourse(String type, String term, String name, String zjr, String zbdw) {
		return courseRepositories.query(type, term, PermissionUtil.toLikeString(name), PermissionUtil.toLikeString(zjr),
				PermissionUtil.toLikeString(zbdw), null, null, RequestContextHolder.get().getPageRequest());
	}

	@RequestMapping("time")
	@ResponseBody
	public long time() {
		return System.currentTimeMillis();
	}

	@RequestMapping("getCourses")
	@ResponseBody
	public Page<CourseInfo> getCourses(String type, String name, String fuzzy) {
		return courseRepositories.query(type, null, PermissionUtil.toLikeString(name), null, null,
				PermissionUtil.toLikeString(fuzzy), new Date(), RequestContextHolder.get().getPageRequest());
	}

	@RequestMapping("getApplyStatus")
	@ResponseBody
	public Object getApplyStatus(String[] ids) {
		if (ids == null) {
			return null;
		}
		if (RequestContextHolder.get().getUser().getType() == 0) {
			StuInfo findOneByXh = stuInfoRepository.findByXh(RequestContextHolder.get().getUser().getUid()).get(0);
			if (findOneByXh != null)
				return courseApplyRepository.findMyApplyByCourseIds(Arrays.asList(ids), findOneByXh.getId());
		}
		return Arrays.asList("");

	}

	@RequestMapping("getMyCourses")
	@ResponseBody
	public Page<CourseInfo> getMyCourses(String type, String fuzzy) {
		return courseApplyRepository.queryMyCourseInfo(RequestContextHolder.get().getUser().getUid(), type,
				PermissionUtil.toLikeString(fuzzy), RequestContextHolder.get().getPageRequest());
	}

	// 申请课程
	@RequestMapping("apply")
	@ResponseBody
	@RequestPermission(value = RequestPermission.STUDENT)
	public Object apply(String courseId) {
		if (!PermissionUtil.isStudent()) {
			return ("只准许学员申请");
		}
		ILock lock = hazelcastInstance.getLock(APPLYCOUNTLOCK);
		lock.lock();
		try {
			Long count = applyCountMap.get(courseId);
			if (count == null) {
				count = courseApplyRepository.countByCourseId(courseId);
				applyCountMap.put(courseId, count);
			}
			CourseInfo courseInfo = courseInfoMap.get(courseId);
			if (courseInfo == null) {
				courseInfo = courseRepositories.findOne(courseId);
				courseInfoMap.put(courseId, courseInfo);
			}
			StuInfo stuInfo = TrainUtil.getCurrentStuInfo(stuInfoRepository, courseInfo.getTerm().getId());
			if (stuInfo == null) {
				return ("只准许学员申请");
			}
			if (stuInfo.getStatus() != 0) {
				return ("您当前学习状态异常,请联系管理员");
			}

			if (!courseInfo.getTerm().getId().equals(stuInfo.getTerm().getId())) {
				return ("非本期次学员不能申请!");
			}
			long time = time();
			if (count < courseInfo.getKcme() && (courseInfo.getKcsj().getTime() > time)
					&& !new Integer(1).equals(courseInfo.getStatus()) && (courseInfo.getFbsj().getTime() < time)) {
				CourseApply courseApply = new CourseApply();
				courseApply.setCourseInfo(courseInfo);
				courseApply.setStatus(0);
				courseApply.setApplyTime(new Date());
				courseApply.setStuInfo(stuInfo);
				courseApplyRepository.save(courseApply);
				applyCountMap.put(courseId, 1 + count);
				return "succ";
			}
			return ("名额已满");
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			lock.unlock();
		}
	}

	@RequestMapping("queryCourseApplies")
	@ResponseBody
	public Page<CourseApply> queryCourseApplies(String course, String name, String grade, String department,
			String major, Integer sfwtzs, Integer sfsqtzs) {
		return null;
	}

	@RequestMapping("getCourseApplyCount")
	@ResponseBody
	public Object getCourseApplyCount(String[] ids) {
		if (ids == null) {
			return null;
		}
		return courseApplyRepository.findCountByCourseId(Arrays.asList(ids));
	}

	@RequestMapping("queryStuInfoByCourseId")
	@ResponseBody
	public Object queryStuInfoByCourseId(String courseId, String name, String department, String clazz) {
		if (courseId == null) {
			return null;
		}
		return courseApplyRepository.queryStuInfoByCourseId(courseId, PermissionUtil.toLikeString(name), department,
				clazz, RequestContextHolder.get().getPageRequest());
	}

	////////////////////////////////////////////////////////////////////////////////
	//
	// 课程学员名单导出
	//
	////////////////////////////////////////////////////////////////////////////////
	@RequestMapping("exportCourseStuInfo")
	@ResponseBody
	public Object exportCourseStuInfo(String courseId, String name, String department, String clazz,
			HttpServletResponse response)
			throws FileNotFoundException, IOException, RowsExceededException, WriteException {
		Page<StuInfo> stuInfoByCourseId = courseApplyRepository.queryStuInfoByCourseId(courseId,
				PermissionUtil.toLikeString(name), department, clazz, new PageRequest(0, Integer.MAX_VALUE));
		File tempFolder = FileHelper.getTempFolder("train_");
		CourseInfo courseInfo = courseRepositories.findOne(courseId);
		if (courseInfo == null) {
			return null;
		}
		String xlsFileName = "课程学员名单-" + courseInfo.getName() + ".xls";
		String xlsFilePath = tempFolder.getAbsolutePath() + "/" + xlsFileName;
		File xlsFile = new File(xlsFilePath);
		response.setContentType("application/octet-stream;charset=UTF-8");
		response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(xlsFileName, "UTF-8"));
		doExportCourseStuInfo(xlsFile, stuInfoByCourseId.getContent());
		OutputStream out = response.getOutputStream();
		FileCopyUtils.copy(new FileInputStream(xlsFile), out);
		out.flush();
		return null;
	}

	private void doExportCourseStuInfo(File xlsFile, List<StuInfo> cList)
			throws IOException, RowsExceededException, WriteException {
		WritableWorkbook book = null;
		String[] headers = { "学号", "姓名", "院系", "班级" };
		try {
			book = Workbook.createWorkbook(xlsFile);
			WritableSheet sheet = book.createSheet("课程发布信息", 0);
			/** 写header */
			for (int i = 0; i < headers.length; i++) {
				sheet.addCell(new Label(i, 0, headers[i]));
			}
			int row = 1;
			for (StuInfo c : cList) {
				UserInfo user = c.getUser();
				try {
					sheet.addCell(new Label(0, row, user.getUid()));
					sheet.addCell(new Label(1, row, user.getName()));
					// TODO 获取院系名
					sheet.addCell(new Label(2, row, user.getDepartment()));
					sheet.addCell(new Label(3, row, c.getClassInfo() != null ? c.getClassInfo().getBjName() : ""));
				} catch (Exception e) {
				}
				row += 1;
			}
			book.write();
		} finally {
			if (book != null)
				try {
					book.close();
				} catch (WriteException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}

	@RequestMapping("passCourseApply")
	@ResponseBody
	public Object passCourseApply(String id) {
		return null;
	}

	@RequestMapping("rejectCourseApply")
	@ResponseBody
	public Object rejectCourseApply(String id) {
		return null;
	}

	@Autowired
	private CourseLeaveApplyRepository courseLeaveApplyRepository;

	// 请假
	@RequestMapping("applyLeave")
	@ResponseBody
	public Object applyLeave(CourseLeaveApply courseLeaveApply) {
		CourseInfo courseInfo = courseLeaveApply.getCourseInfo();
		String id = courseInfo.getId();
		courseInfo = courseRepositories.findOne(id);
		if (!"1".equals(courseInfo.getKclb()) || !canApplyLeave(courseInfo.getTerm().getId())) {
			return null;
		}
		courseLeaveApply.setStuInfo(stuInfoRepository.findOneByXhAndTerm(RequestContextHolder.get().getUser().getUid(),
				courseInfo.getTerm().getId()));
		courseLeaveApply.setStatus(1);
		return courseLeaveApplyRepository.save(courseLeaveApply);
	}

	@RequestMapping("canApplyLeave")
	@ResponseBody
	public boolean canApplyLeave(String term) {
		CourseLeaveApply apply = courseLeaveApplyRepository.findByStatusInAndStuInfo(Arrays.asList(2, 3),
				stuInfoRepository.findOneByXhAndTerm(RequestContextHolder.get().getUser().getUid(), term));
		return apply == null;
	}

	@RequestMapping("getApplyLeaves")
	@ResponseBody
	public Object getApplyLeaves(String[] courseId) {
		if (courseId == null) {
			return null;
		}
		return courseLeaveApplyRepository.findByCourseInfoIdInAndStuInfoUserUid(Arrays.asList(courseId),
				RequestContextHolder.get().getUser().getUid());
	}

	@RequestMapping("getStuApplyLeaveCount")
	@ResponseBody
	public Object getStuApplyLeaveCount(String[] stuId) {
		if (stuId == null) {
			return null;
		}
		return courseLeaveApplyRepository.queryCountByStuInfoIdIn(Arrays.asList(stuId));
	}

	@RequestMapping("queryLeaves")
	@ResponseBody
	public Page<CourseLeaveApply> queryLeaves(String term, String course, String type, String stuName,
			String department, String clazz, Integer status) {
		return courseLeaveApplyRepository.query(term, course, type, PermissionUtil.toLikeString(stuName), department,
				clazz, null, TrainUtil.getFilteredStatusArray(status), RequestContextHolder.get().getPageRequest());
	}

	@RequestMapping("auditLeave")
	@ResponseBody
	@Transactional
	public Object auditLeave(String id, boolean pass) {
		CourseLeaveApply leaveApply = courseLeaveApplyRepository.findOne(id);
		if (leaveApply != null && PermissionUtil.getFilteredStatus(null) == leaveApply.getStatus()) {
			int status = leaveApply.getStatus() + 1;
			if (!pass) {
				status = -1;
			}
			leaveApply.setStatus(status);
			courseLeaveApplyRepository.save(leaveApply);
		}
		return "succ";
	}

	@RequestMapping("batchAuditLeave")
	@ResponseBody
	@Transactional
	public Object batchAuditLeave(String[] id, boolean pass) {
		if (id == null) {
			return "";
		}
		List<CourseLeaveApply> all = courseLeaveApplyRepository.findAll(Arrays.asList(id));
		for (CourseLeaveApply leaveApply : all) {
			if (leaveApply != null && PermissionUtil.getFilteredStatus(null) == leaveApply.getStatus()) {
				int status = leaveApply.getStatus() + 1;
				if (!pass) {
					status = -1;
				}
				leaveApply.setStatus(status);
				courseLeaveApplyRepository.save(leaveApply);
			}
		}
		return "succ";
	}

	@RequestMapping("queryAttendance")
	@ResponseBody
	public Page<CourseAttendance> queryAttendance(String course, String courseName, String major, String stuName,
			String department, String clazz, Integer status) {
		return courseAttendanceRepository.query(course, PermissionUtil.toLikeString(courseName),
				PermissionUtil.toLikeString(stuName), department, major, clazz, status,
				RequestContextHolder.get().getPageRequest());
	}

	// 出席
	@RequestMapping("queryAttend")
	@ResponseBody
	public Object queryAttend(String[] courseId) {
		if (courseId == null) {
			return null;
		}
		return courseAttendanceRepository.findByCourseInfoIdIn(Arrays.asList(courseId));
	}

	// 出席
	@RequestMapping("getMyAttend")
	@ResponseBody
	public Object getMyAttend(String[] courseId) {
		if (courseId == null) {
			return null;
		}
		return courseAttendanceRepository.findByCourseInfoIdInAndStuInfoUserUid(Arrays.asList(courseId),
				RequestContextHolder.get().getUser().getUid());
	}

	@RequestMapping("updateAttendance")
	@ResponseBody
	public Object updateAttendance(CourseAttendance attendance) {
		courseAttendanceRepository.save(attendance);
		return "success";
	}

	@RequestMapping("generateAttendance")
	@ResponseBody
	@Transactional
	public Object generateAttendance(String course, Boolean absence) {
		int status = 0;
		if (Boolean.TRUE == absence) {
			status = 2;
		}
		List<CourseApply> courseApplys = courseApplyRepository.findCourseApplys(course, null, null, null, null, null);
		List<CourseAttendance> toSave = new ArrayList<CourseAttendance>();
		Map<String, CourseAttendance> attendanceMap = new HashMap<String, CourseAttendance>();
		List<String> students = new ArrayList<String>();
		for (CourseApply apply : courseApplys) {
			CourseAttendance attendance = courseAttendanceRepository
					.findOneByCourseInfoAndStuInfo(apply.getCourseInfo(), apply.getStuInfo());
			if (attendance == null)
				attendance = new CourseAttendance();
			attendance.setStuInfo(apply.getStuInfo());
			attendance.setCourseInfo(apply.getCourseInfo());
			attendance.setStatus(status);
			toSave.add(attendance);
			students.add(apply.getStuInfo().getId());
			attendanceMap.put(apply.getStuInfo().getId(), attendance);
		}
		List<CourseLeaveApply> leaveApplis = courseLeaveApplyRepository
				.findByCourseInfoIdAndStuInfoIdInAndStatus(course, students, 3);
		for (CourseLeaveApply apply : leaveApplis) {
			CourseAttendance attendance = attendanceMap.get(apply.getStuInfo().getId());
			if (attendance != null) {
				attendance.setStatus(1);
			}
		}
		// TODO safe save
		courseAttendanceRepository.save(toSave);
		return "success";
	}

	////////////////////////////////////////////////////////////////////////////////
	//
	// 请假导入导出
	//
	////////////////////////////////////////////////////////////////////////////////
	@RequestMapping("importAttendance")
	@ResponseBody
	public Object importAttendance(MultipartFile file, String term, HttpServletResponse response) throws Exception {

		File tempFolder = FileHelper.getTempFolder("train_");
		String xlsFilePath = tempFolder.getAbsolutePath() + "/" + file.getOriginalFilename();
		File xlsFile = new File(xlsFilePath);
		FileUtils.copyInputStreamToFile(file.getInputStream(), xlsFile);
		return doImportAttendance(xlsFile, term);
	}

	private final static List<String> ATTENDANCE_IMP_HEADERS = Arrays.asList(new String[] { "学号", "课程", "考勤状态" });

	private String doImportAttendance(File xlsFile, String term) throws BiffException, IOException {
		Workbook workbook = Workbook.getWorkbook(xlsFile);
		Sheet sheet = workbook.getSheet(0);
		int rows = sheet.getRows();
		int columns = sheet.getColumns();
		/** Main content */
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		/** Headers */
		// ["学号", "课程", "考勤状态"]
		List<String> headers = new ArrayList<String>();
		for (int row = 0; row < rows; row++) {
			Map<String, String> map = new LinkedHashMap<String, String>();
			for (int col = 0; col < columns; col++) {
				String s = sheet.getCell(col, row).getContents();
				if (row == 0) {
					headers.add(s != null ? s.trim().toLowerCase() : "");
				} else {
					map.put(headers.get(col), s != null ? s.trim() : "");
				}
			}
			if (row != 0)
				list.add(map);
		}
		// 校验header
		if (!ArrayUtils.isEquals(headers, ATTENDANCE_IMP_HEADERS)) {
			return "导入的文件中的表头不正确，应该是：" + ATTENDANCE_IMP_HEADERS;
		}
		// 逐行处理数据
		StringBuffer message = new StringBuffer();
		final List<CourseAttendance> allList = new ArrayList<CourseAttendance>();
		for (Map<String, String> row : list) {
			String xh = row.get("学号");
			String course = row.get("课程");
			String kqzt = row.get("考勤状态");
			StuInfo stuInfo = stuInfoRepository.findOneByXhAndTerm(xh, term);
			if (stuInfo == null) {
				message.append("学号" + xh + "不存在\n");
				continue;
			}
			CourseInfo courseInfo = courseRepositories.findOneByNameAndTerm(course, term);
			if (courseInfo == null) {
				message.append("课程" + course + "不存在\n");
				continue;
			}
			CourseAttendance ca = courseAttendanceRepository.findOneByCourseInfoAndStuInfo(courseInfo, stuInfo);
			if (ca == null) {
				ca = new CourseAttendance();
				ca.setStuInfo(stuInfo);
				ca.setCourseInfo(courseInfo);
			}
			int status = kqzt.equals("正常") ? 0 : (kqzt.equals("请假") ? 1 : 2);
			ca.setStatus(status);
			allList.add(ca);
		}
		if (allList.size() > 0) {
			courseAttendanceRepository.save(new Iterable<CourseAttendance>() {
				@Override
				public Iterator<CourseAttendance> iterator() {
					return allList.iterator();
				}
			});
		}
		return message.toString();
	}

	@RequestMapping("exportAttendance")
	@ResponseBody
	public Object exportAttendance(String term, HttpServletResponse response)
			throws FileNotFoundException, IOException, RowsExceededException, WriteException {
		List<CourseAttendance> cList = courseAttendanceRepository.findByTerm(term);
		File tempFolder = FileHelper.getTempFolder("train_");
		String xlsFileName = "考勤信息.xls";
		String xlsFilePath = tempFolder.getAbsolutePath() + "/" + xlsFileName;
		File xlsFile = new File(xlsFilePath);
		response.setContentType("application/octet-stream;charset=UTF-8");
		response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(xlsFileName, "UTF-8"));
		doExportAttendance(xlsFile, cList);
		OutputStream out = response.getOutputStream();
		FileCopyUtils.copy(new FileInputStream(xlsFile), out);
		out.flush();
		return null;
	}

	private void doExportAttendance(File xlsFile, List<CourseAttendance> cList)
			throws IOException, RowsExceededException, WriteException {
		WritableWorkbook book = null;
		String[] headers = { "课程名称", "课程类型", "开课时间", "学号", "姓名", "年级", "院系", "班级", "课程考勤状态" };
		try {
			book = Workbook.createWorkbook(xlsFile);
			WritableSheet sheet = book.createSheet("请假信息", 0);
			/** 写header */
			for (int i = 0; i < headers.length; i++) {
				sheet.addCell(new Label(i, 0, headers[i]));
			}
			int row = 1;
			for (CourseAttendance ca : cList) {
				CourseInfo c = ca.getCourseInfo();
				StuInfo s = ca.getStuInfo();
				sheet.addCell(new Label(0, row, c.getName()));
				sheet.addCell(new Label(1, row, c.getKclb()));
				sheet.addCell(new Label(2, row, dateFormat.format(c.getKcsj())));
				sheet.addCell(new Label(3, row, s.getUser().getUid()));
				sheet.addCell(new Label(4, row, s.getUser().getName()));
				sheet.addCell(new Label(5, row, s.getUser().getGrade()));
				sheet.addCell(new Label(6, row, s.getUser().getDepartment()));
				sheet.addCell(new Label(7, row, s.getClassInfo().getBjName()));
				sheet.addCell(new Label(8, row, ca.getStatusString()));
				row += 1;
			}
			book.write();
		} finally {
			if (book != null)
				try {
					book.close();
				} catch (WriteException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}

	////////////////////////////////////////////////////////////////////////////////
	//
	// 课程导出
	//
	////////////////////////////////////////////////////////////////////////////////
	@RequestMapping("exportCourse")
	@ResponseBody
	public Object exportCourse(String term, HttpServletResponse response)
			throws FileNotFoundException, IOException, RowsExceededException, WriteException {
		Page<CourseInfo> cList = courseRepositories.query(null, term, null, null, null, null, null,
				new PageRequest(0, Integer.MAX_VALUE));
		File tempFolder = FileHelper.getTempFolder("train_");
		String xlsFileName = "课程发布信息.xls";
		String xlsFilePath = tempFolder.getAbsolutePath() + "/" + xlsFileName;
		File xlsFile = new File(xlsFilePath);
		response.setContentType("application/octet-stream;charset=UTF-8");
		response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(xlsFileName, "UTF-8"));
		doExportCourse(xlsFile, cList.getContent());
		OutputStream out = response.getOutputStream();
		FileCopyUtils.copy(new FileInputStream(xlsFile), out);
		out.flush();
		return null;
	}

	private void doExportCourse(File xlsFile, List<CourseInfo> cList)
			throws IOException, RowsExceededException, WriteException {
		WritableWorkbook book = null;
		String[] headers = { "课程名称", "课程类型", "主讲人", "开课时间", "开课状态", "发布时间", "课程名额", "已报名" };
		try {
			book = Workbook.createWorkbook(xlsFile);
			WritableSheet sheet = book.createSheet("课程发布信息", 0);
			/** 写header */
			for (int i = 0; i < headers.length; i++) {
				sheet.addCell(new Label(i, 0, headers[i]));
			}
			int row = 1;
			for (CourseInfo c : cList) {
				sheet.addCell(new Label(0, row, c.getName()));
				sheet.addCell(new Label(1, row, c.getKclb()));
				sheet.addCell(new Label(2, row, c.getZjr()));
				sheet.addCell(new Label(3, row, dateFormat.format(c.getKcsj())));
				sheet.addCell(new Label(4, row, c.getStatusString()));
				sheet.addCell(new Label(5, row, dateFormat.format(c.getFbsj())));
				sheet.addCell(new Label(6, row, c.getKcme().toString()));
				sheet.addCell(new Label(7, row, courseApplyRepository.countByCourseId(c.getId()).toString()));
				row += 1;
			}
			book.write();
		} finally {
			if (book != null)
				try {
					book.close();
				} catch (WriteException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		applyCountMap = hazelcastInstance.getMap(APPLYCOUNTKEY);
		courseInfoMap = hazelcastInstance.getMap(COURSEINFOKEY);
	}
}
